package com.ucitymetro.ucitymc.autosecurity.aspect;
import com.ucitymetro.ucitymc.autosecurity.annotation.*;
import com.ucitymetro.ucitymc.autosecurity.config.SecretKeyConfig;
import com.ucitymetro.ucitymc.autosecurity.utils.*;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

@Aspect
@Component
public class AutoSecurityAspect {

    @Autowired
    private SecretKeyConfig config;

    @Around("@annotation(com.ucitymetro.ucitymc.autosecurity.annotation.Security)")
    public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable {
        try{
            Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
            Annotation[][] parameterAnnotations = method.getParameterAnnotations();
            final Object[] args = joinPoint.getArgs();
            // 带特定注解的参数下标集合
            for (int i = 0; i < parameterAnnotations.length; i++) {
                for (Annotation an : parameterAnnotations[i]) {
                    String originValue = String.valueOf(args[i]);
                    try{
                        if (an instanceof RSADecrypt) {
                            String decrypt = RSAUtils.publicDecrypt(originValue, config.getRsaPublicKey());
                            args[i] = decrypt;
                        }else if (an instanceof RSAEncrypt) {
                            String encrypt = RSAUtils.privateEncrypt(originValue, config.getRsaPrivateKey());
                            args[i] = encrypt;
                        }else if (an instanceof AESDecrypt) {
                            String decrypt = AESUtils.decrypt(originValue, config.getAesKey());
                            args[i] = decrypt;
                        }else if (an instanceof AESEncrypt) {
                            String decrypt = AESUtils.encrypt(originValue, config.getAesKey());
                            args[i] = decrypt;
                        }else if (an instanceof MD5Encrypt) {
                            String encrypt = MD5Utils.encrypt(originValue);
                            args[i] = encrypt;
                        }else if (an instanceof BASE64Decrypt) {
                            String decrypt = BASE64Utils.decrypt(originValue);
                            args[i] = decrypt;
                        }else if (an instanceof BASE64Encrypt) {
                            String encrypt = BASE64Utils.encrypt(originValue);
                            args[i] = encrypt;
                        }else if (an instanceof SHA1Encrypt) {
                            String encrypt = SHA1Utils.encrypt(originValue);
                            args[i] = encrypt;
                        }else if (an instanceof DESDecrypt) {
                            String decrypt = DESUtils.decrypt(originValue, config.getDesKey());
                            args[i] = decrypt;
                        }else if (an instanceof DESEncrypt) {
                            String encrypt = DESUtils.encrypt(originValue, config.getDesKey());
                            args[i] = encrypt;
                        }
                    }catch (Exception e){
                        e.printStackTrace();
                        return joinPoint.proceed();
                    }
                }
            }
            // 返回参数
            return joinPoint.proceed(args);
        }catch (Exception e){
            e.printStackTrace();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }finally {
            return joinPoint.proceed();
        }
    }
}